package top.yekongle.feature.java8.lambda;

import org.junit.Test;

import java.util.*;
import java.util.function.Consumer;

/**
 * Lambda 表达式的基础语法：JAVA8 中引入了一个新的操作符 "->" 该操作符称为箭头操作符 或 lambda 操作符
 * 箭头操作符将 Lambda 表达式拆分为两个部分
 * 左侧： Lambda 表达式的参数列表
 * 右侧：Lambda 表达式中所需执行的功能，即 Lambda 体
 *
 * 语法格式一：无参数，无返回值
 *      () -> System.out.pirntln("hello");
 *
 * 语法格式二：有一个参数无返回值
 *      (x) -> System.out.pirntln(x);
 *
 * 语法格式三：有两个以上的参数有返回值，并且 Lambada 体中有多条语句
 *
 * 语法格式四：若  Lambda 体中只有一条语句，return 和大括号都可以省略不写
 *      Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
 *
 * 语法格式五：Lambda 表达式的参数列表的数据类型可以省略不写，因为 JVM 编译器通过上下文推断出，数据类型，即"类型推断"
 *
 * 二、Lambda 表达式需要函数式接口的支持
 * 函数式接口：接口中只有一个抽象方法的接口，称为函数式接口。可以使用注解 @FunctionalInterface 修饰, 可以检查是否是
 * 函数式接口
 * */
public class LambdaTest2 {
    public void test1() {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        };
        r.run();

        System.out.println("-------------------------------");
        Runnable r1 = () -> System.out.println("Hello World");
        r1.run();
    }

    public void test2() {
        Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con.accept("Hello");
        System.out.println("-------------------------------");
        Consumer<String> con1 = (x) -> System.out.println(x);
        con1.accept("Hello world");

        Consumer<String> con2 = x -> System.out.println(x);
        con1.accept("Hello world!!!");
    }

    public void test3(){
        Comparator<Integer> com = (x,y)-> {
            System.out.println("函数式接口");
            return Integer.compare(x,y);

        };
    }

    public void test4(){
        Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
    }

    // 需求： 对一个数进行运算
    public void test5() {
        Integer num = operation(100, (x)-> x*x);
        System.out.println(num);

        Integer num1 = operation(100,(y)-> y+y);
        System.out.println(num1);
    }

    public Integer operation(Integer num, MyFun mf) {
        return mf.getValue(num);
    }

    List<Employee> employees = Arrays.asList(
            new Employee("张三", 18, 5555.55, null),
            new Employee("李四", 19, 6666.66, null)
    );

    public void test6() {
        Collections.sort(employees, (e1, e2)->{
            if (e1.getAge() == e2.getAge()) {
                return e1.getName().compareTo(e2.getName());
            } else {
                return -Integer.compare(e1.getAge(), e2.getAge());
            }
        });

        for (Employee emp : employees) {
            System.out.println(emp);
        }
    }


    public void test7() {
        String result = strHandler("hello", (s)-> s.toUpperCase());
        System.out.println(result);
    }

    // 用户处理字符串
    public String strHandler(String str, MyFun1 myFun1) {
        return myFun1.getValue(str);
    }


    // 计算两个 Long 型参数的和
    public long calNumber(Long l1, Long l2, MyFun2<Long,Long> myFun2) {
        return myFun2.calNum(l1, l2);
    }

    public void test8() {
        long result = calNumber(100L, 200L, (x,y) -> x + y);
        System.out.println(result);
    }
}
